package nyist.media.service.impl;

import nyist.media.bean.role.RoleInfoBean;
import nyist.media.bean.role.RoleListBean;
import nyist.media.bean.role.RoleOptionBean;
import nyist.media.entity.admin.Role;
import nyist.media.exception.BusinessException;
import nyist.media.page.ApiResult;
import nyist.media.page.AppPage;
import nyist.media.repository.MenuAuthRepository;
import nyist.media.repository.RoleRepository;
import nyist.media.service.RoleService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : dcf
 * @date : 2019/3/12
 */

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private MenuAuthRepository menuAuthRepository;

    @Override
    public List<RoleOptionBean> findAll() {
        List<Role> list = roleRepository.findAll();
        return list.stream().map(RoleOptionBean::new).collect(Collectors.toList());
    }

    @Override
    public RoleInfoBean getInfo(Long roleId) {
        return new RoleInfoBean(roleRepository.findOne(roleId));
    }

    @Override
    public AppPage<RoleListBean> findPage(PageRequest pageRequest) {
        Page<Role> page = roleRepository.findAll(pageRequest);
        List<RoleListBean> list = page.getContent().stream().map(RoleListBean::new).collect(Collectors.toList());
        return new AppPage<>(pageRequest, page.getTotalElements(), page.getTotalPages(), list);
    }

    @Override
    public void update(RoleInfoBean param) {
        Role role = roleRepository.findOne(param.getId());
        if (role.isRoleDef()) {
            throw new BusinessException(ApiResult.ILLEGAL_PARAMS, "默认角色无法修改");
        }
        role.setName(param.getName());
        if (ArrayUtils.isNotEmpty(param.getMenuAuthIds())) {
            role.setAuths(new HashSet<>(menuAuthRepository.findAll(Arrays.asList(param.getMenuAuthIds()))));
        }
        roleRepository.save(role);
    }

    @Override
    public void save(RoleInfoBean param) {
        Role role = new Role();
        Date now = new Date();
        role.setRoleDef(false);
        role.setName(param.getName());
        if (!ArrayUtils.isEmpty(param.getMenuAuthIds())) {
            role.setAuths(new HashSet<>(menuAuthRepository.findAll(Arrays.asList(param.getMenuAuthIds()))));
        }
        role.setCreateDate(now);
        role.setModifyDate(now);
        roleRepository.save(role);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Long[] ids) throws BusinessException {
        for (Long id : ids) {
            delete(id);
        }
    }

    /**
     * 删除角色
     *
     * @param id 角色ID
     * @throws BusinessException 自定义异常对象
     */
    private void delete(Long id) throws BusinessException {
        Role role = roleRepository.findOne(id);
        if (role.isRoleDef()) {
            throw new BusinessException(ApiResult.ILLEGAL_PARAMS, "默认角色无法删除");
        }
        if (role.getAdmins() != null && !role.getAdmins().isEmpty()) {
            throw new BusinessException(ApiResult.ILLEGAL_PARAMS, "已关联管理员，请先解除关联");
        }
        roleRepository.delete(role);
    }
}

